package com.kongchengji.zhanguafou.service;

import com.kongchengji.zhanguafou.dao.QuartzDAO;
import com.kongchengji.zhanguafou.domain.QuartzDO;
import com.kongchengji.zhanguafou.domain.Result;
import org.quartz.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import tk.mybatis.mapper.entity.Example;

import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class QuartzService {
    @Autowired
    @Qualifier("Scheduler")
    private Scheduler scheduler;
    @Autowired
    QuartzDAO quartzDAO;
    Logger logger = LoggerFactory.getLogger(QuartzService.class);

    /**
     * 判断数据库中的任务是否运行
     * @param jobGroup 任务分组
     * @param openId   用户标识
     * @return 返回任务运行标识
     * @throws SchedulerException
     */
    public Map<String,String> checkJobRun(String jobGroup,String openId) throws SchedulerException {
        Map<String,String> map = new HashMap<>();
        Example example = new Example(QuartzDO.class);
        example.createCriteria().andEqualTo("jobGroup",jobGroup).andEqualTo("openId",openId);
        List<QuartzDO> quartzDOS = quartzDAO.selectByExample(example);
        JobKey key;
        Boolean isExist;
        for(QuartzDO quartzDO : quartzDOS) {
            key = new JobKey(quartzDO.getJobName(), quartzDO.getJobGroup());
            isExist = scheduler.checkExists(key);
            map.put(quartzDO.getUrl(),isExist?"checked":"");
        }
        return map;
     }

    /**
     * 修改任务的参数
     * @param quartzDO 要修改的任务
     * @return
     */
    public Result  editQuartzDO(QuartzDO quartzDO) throws SchedulerException {
        //1.将修改的任务保存数据库
        quartzDAO.updateByPrimaryKeySelective(quartzDO);
        //2.查询出当前运行任务的信息
        QuartzDO quartz = quartzDAO.selectOne(quartzDO);
        //3.删除原有运行的任务
        TriggerKey triggerKey = TriggerKey.triggerKey(quartz.getJobName(), quartz.getJobGroup());
        // 停止触发器
        scheduler.pauseTrigger(triggerKey);
        // 移除触发器
        scheduler.unscheduleJob(triggerKey);
        //删除任务
        scheduler.deleteJob(JobKey.jobKey(quartz.getJobName(),quartz.getJobGroup()));
        //4.重新启动任务
        return initTask(quartz);
    }

    /**
     * 开启任务
     * @param jobName
     */
    public void  turnOnTask(String jobName) {
        Example example = new Example(QuartzDO.class);
        example.createCriteria().andEqualTo("jobName",jobName);
        QuartzDO quartz = quartzDAO.selectOneByExample(example);
        //启动任务
        initTask(quartz);
    }

    /**
     * 关闭任务
     * @param jobName 任务标识
     */
    public void turnDownTask(String jobName)  {
        Example example = new Example(QuartzDO.class);
        example.createCriteria().andEqualTo("jobName",jobName);
        QuartzDO quartz = quartzDAO.selectOneByExample(example);
        TriggerKey triggerKey = TriggerKey.triggerKey(quartz.getJobName(), quartz.getJobGroup());
        try {
            // 停止触发器
            scheduler.pauseTrigger(triggerKey);
            // 移除触发器
            scheduler.unscheduleJob(triggerKey);
            // 删除任务
            scheduler.deleteJob(JobKey.jobKey(quartz.getJobName(), quartz.getJobGroup()));
        } catch (Exception e) {
            logger.error("执行计划任务失败");
        }

    }



    /**
     * 初始化任务
     * @param quartz 要初始化任务
     * @return
     */
    private Result initTask(QuartzDO quartz) {
        Class cls;
        try {
            cls = Class.forName(quartz.getJobClassName());
        } catch (ClassNotFoundException e) {
            logger.error("不存在该任务类");
            return Result.error("不存在该任务类");
        }
        //构建job信息
        JobDetail job = JobBuilder.newJob(cls).withIdentity(quartz.getJobName(),
                quartz.getJobGroup())
                .withDescription(quartz.getDescription()).build();
        job.getJobDataMap().put("quartz",quartz);
        // 触发时间点
        CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(quartz.getCronExpression());
        Trigger trigger = TriggerBuilder.newTrigger().withIdentity("trigger" + quartz.getJobName(), quartz.getJobGroup())
                .startNow().withSchedule(cronScheduleBuilder).build();
        //交由Scheduler安排触发
        try {
            scheduler.scheduleJob(job, trigger);
        } catch (SchedulerException e) {
            logger.error("任务启动失败");
            return Result.error("任务启动失败");
        }
        return Result.ok("修改配置成功");
    }
}
